/**
 * \file Файл описания класса PlotData2D
 *
 * Файл содержит определение класса для отрисовки графика 2D
 */

#ifndef PLOTDATA2D_H
#define PLOTDATA2D_H

#include <boost/circular_buffer.hpp>
#include <boost/algorithm/minmax_element.hpp>
#include "plotdata.h"

using namespace boost;
using namespace Glib;

/**
 * @brief Класс рисования графика 2D
 *
 * Класс отнаследован от класса PlotData
 * данные для осей x,y беруться из массивов m_x m_y, соответственно
 * данные для оси X это временные метки Timestamp
 *
 */
class PlotData2D :public PlotData {
       PlotData2D &operator = (const PlotData2D &) = delete;
        PlotData2D (const PlotData2D &source) = delete;

    protected:

        unsigned long long  m_x_min;///< минимальное значение по оси Х на отрисовываемом интервале
        unsigned long long  m_x_max;///< максимальное значение по оси Х на отрисовываемом интервале
        double  m_y_min;///< минимальное значение по оси Y на отрисовываемом интервале
        double  m_y_max;///< максимальное значение по оси Y на отрисовываемом интервале
        double  m_Y_offset_min;///< добавка к минимуму оси Y для масштабирования
        double  m_Y_offset_max;///< добавка к максимуму оси Y для масштабирования
        circular_buffer<unsigned long long>     m_x{MAX_INDEX_CIRCULAR_BUFFER};
        circular_buffer<double>                  m_y{MAX_INDEX_CIRCULAR_BUFFER};
        /**
         * @brief Вычисляет минимумы и максимумы в массивах X  и Y
         *
         * Минимум и максимум массива Х помещает в m_x_min и m_x_max соответственно
         * Минимум и максимум массива Y помещает в m_y_min и m_y_max соответственно
         * @param x_interval_begin индекс начала массива
         * @param x_interval_end индекс начала массива. Если 0 - то до конца массива
         */
        void CalculateMaxMin(uint32_t x_interval_begin, uint32_t x_interval_end);

    public:

        /**
         * @brief Конструктор создания графика 2D
         *
         * @param color цвет линии RGBA
         * @param line_style стиль линии
         * @param line_width толщина линии
         * @param name название графика
         */
        PlotData2D(Gdk::RGBA color,
                   LineStyle line_style,
                   double line_width,
                   ustring name);

        /**
         * @brief Добавляет элемент в массив X
         *
         * Значение элемента добавляется в конец массива
         * @param x добавляемое значение
         */
        void AddDataToX( unsigned long long  x);

        /**
         * @brief Добавляет элемент в массив Y
         *
         * @param y добавляемое значение
         */
        void AddDataToY(double y);

        /**
         * @brief Отрисовка графика
         *
         * @param cr контекст Cairomm
         * @param width ширина области отрисовки
         * @param height высота области отрисовки
         * @param x_interval_begin индекса массива для начальных значений
         * @param x_interval_end индекса массива для конечных значений (Если 0 - то до конца массива)
         * @param y_offset_min добавка к вычесленному минимуму массива Y для масштабирования (Если 999- то устанавливает ноль, если 0- оставляет предыдущие значения)
         * @param y_offset_max добавка к вычесленному максимуму массива Y для масштабирования (Если 999- то устанавливает ноль, если 0- оставляет предыдущие значения)
         */
        void DataDraw(const Cairo::RefPtr<Cairo::Context> &cr,
                      uint16_t width,
                      uint16_t height,
                      uint32_t x_interval_begin,
                      uint32_t x_interval_end,
                      double y_offset_min,
                      double y_offset_max) override;

                      /**
                       * @brief Вычисление количество элементов масиивах X и Y
                       *
                       * @return uint32_t размер массивов X и Y
                       */
        uint32_t GetSize();

        /**
         * @brief Возращает добавку к вычесленному минимуму массива Y для масштабирования
         *
         * @return double добавка к вычесленному минимуму массива Y для масштабирования
         */
        double GetMinOffsetY();

        /**
         * @brief Возращает добавку к вычесленному максимуму массива Y для масштабирования
         *
         * @return double добавка к вычесленному максимуму массива Y для масштабирования
         */
        double GetMaxOffsetY();

        /**
         * @brief Возвращает минимум массива X на выбранном интервале
         *
         * @return long long unsigned int минимальное значение
         */
        unsigned long long GetMinX();

        /**
         * @brief Возвращает максимум массива X на выбранном интервале
         *
         * @return long long unsigned int максимальное значение
         */
        unsigned long long GetMaxX();

        /**
         * @brief Возвращает минимум массива Y на выбранном интервале
         *
         * @return double минимальное значение
         */
        double GetMinY();

        /**
         * @brief Возвращает максимум массива Y на выбранном интервале
         *
         * @return double минимальное значение
         */
        double GetMaxY();

    };
#endif // PLOTDATA2D_H
